/****************************************************************************
 *
 * Copyright (C) 2003-2010 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.dataset.firewall;

import java.util.StringTokenizer;

import nfse.NetFSERecord;
import nfse.NetFSEUtil;
import nfse.gui.record.FlexRecordField;
import nfse.gui.server.GUIRecordFactory;
import nfse.gui.server.RecordBuilderUtil;

public class IPTablesRecordFactory extends GUIRecordFactory<IPTablesRecord> {

    public IPTablesRecordFactory() {
        builder = new RecordBuilderUtil();
        builder.addColumn(null,"ID", RecordBuilderUtil.BIGINT);
        RecordBuilderUtil.SQLField field = builder.addColumn("startts", RecordBuilderUtil.TIMESTAMP);
        field = builder.addColumn("Src IP","srcip", RecordBuilderUtil.INET);
        field = builder.addColumn("Src Port","srcport", RecordBuilderUtil.INTEGER);
        field.setSubtype(FlexRecordField.SUB_TYPE_PORT);
        field = builder.addColumn("Dst IP","dstip", RecordBuilderUtil.INET);
        field = builder.addColumn("Dst Port","dstport", RecordBuilderUtil.INTEGER);
        field.setSubtype(FlexRecordField.SUB_TYPE_PORT);
        field = builder.addColumn("Protocol","protocol", RecordBuilderUtil.INTEGER);
        field.setSubtype(FlexRecordField.SUB_TYPE_PROTOCOL);
        field = builder.addColumn("Ethernet In","ethin", RecordBuilderUtil.VARCHAR,50);
        field = builder.addColumn("Ethernet Out","ethout", RecordBuilderUtil.VARCHAR,50);
        field = builder.addColumn("Physical In","physin", RecordBuilderUtil.VARCHAR,50);
        field = builder.addColumn("Physical Out","physout", RecordBuilderUtil.VARCHAR,50);
        field = builder.addColumn("TTL","ttl", RecordBuilderUtil.INTEGER);
        field = builder.addColumn("TOS","tos", RecordBuilderUtil.VARCHAR,10);
        field = builder.addColumn("Action","action", RecordBuilderUtil.VARCHAR,50);
    }
    
    @Override
    protected void setValues(IPTablesRecord record, int id) {
        int idx = -1;
        builder.setFieldValue(++idx, "" + id);
        builder.setFieldValue(++idx, "" + record.getStartTS());
        builder.setFieldValue(++idx, record.getSrcAddr());
        builder.setFieldValue(++idx, "" + record.srcPort);
        builder.setFieldValue(++idx, record.dstAddr);
        builder.setFieldValue(++idx, "" + record.dstPort);
        builder.setFieldValue(++idx, "" + record.proto);
        builder.setFieldValue(++idx, "" + record.interfaceIn);
        builder.setFieldValue(++idx, "" + record.interfaceOut);
        builder.setFieldValue(++idx, "" + record.physicalInterfaceIn);
        builder.setFieldValue(++idx, "" + record.physicalInterfaceOut);
        builder.setFieldValue(++idx, "" + record.ttl);
        builder.setFieldValue(++idx, "" + record.tos);
        builder.setFieldValue(++idx, record.action );
    }
    
    @Override
    public NetFSERecord generate(String line, int sensor) throws Exception {

        // Record of the form: ts;srcip;May 29 09:17:11 hs62-logger IN=br0
        // OUT=br0
        // PHYSIN=eth0 PHYSOUT=eth1 SRC=146.138.87.221 DST=146.138.199.110
        // LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=79 PROTO=UDP SPT=137 DPT=137
        // LEN=58
        IPTablesRecord rec = new IPTablesRecord(sensor);

        rec.setInitialString(line);
        rec.setStartTS(NetFSEUtil.timestampFromSyslog(line));
        rec.setSrcIP(-1);
        rec.dstIP = -1;

        StringTokenizer st = new StringTokenizer(line);

        String token = st.nextToken();
        while (!token.endsWith(":")) { // Advance to the end of the header
            try {
                token = st.nextToken();
            } catch (java.util.NoSuchElementException e) {
                return null;
            }
        }

        while (st.hasMoreTokens()) {
            token = st.nextToken();
            String[] tokens2 = token.split("=");
            if (token.indexOf("=") == -1) {
                rec.action += token + " ";
            } else if (tokens2.length == 2) {
                if (tokens2[0].equals("SRC")) {
                    rec.setSrcAddr(tokens2[1]);
                    rec.setSrcIP(NetFSEUtil.convertIPtoLong(rec.getSrcAddr()));
                } else if (tokens2[0].equals("DST")) {
                    rec.dstAddr = tokens2[1];
                    rec.dstIP = NetFSEUtil.convertIPtoLong(rec.dstAddr);
                } else if (tokens2[0].equals("PREC")) {
                    rec.prec = tokens2[1];
                } else if (tokens2[0].equals("TTL")) {
                    rec.ttl = Integer.parseInt(tokens2[1]);
                } else if (tokens2[0].equals("TOS")) {
                    rec.tos = tokens2[1];
                } else if (tokens2[0].equals("ID")) {
                    rec.id = tokens2[1];
                } else if (tokens2[0].equals("PROTO")) {
                    rec.proto = NetFSEUtil.getProtocolValue(tokens2[1]);
                } else if (tokens2[0].equals("SPT")) {
                    rec.srcPort = Integer.parseInt(tokens2[1]);
                } else if (tokens2[0].equals("DPT")) {
                    rec.dstPort = Integer.parseInt(tokens2[1]);
                } else if (tokens2[0].equals("IN")) {
                    rec.interfaceIn = tokens2[1];
                } else if (tokens2[0].equals("OUT")) {
                    rec.interfaceOut = tokens2[1];
                } else if (tokens2[0].equals("PHYSIN")) {
                    rec.physicalInterfaceIn = tokens2[1];
                } else if (tokens2[0].equals("PHYSOUT")) {
                    rec.physicalInterfaceOut = tokens2[1];
                }
            }
        }
        rec.action = rec.action.trim();
        if (rec.action.endsWith(":"))
            rec.action = rec.action.substring(0, rec.action.length() - 2);
        if (rec.getSrcIP() == -1 || rec.dstIP == -1)
            return null;
        return rec;

    }

    @Override
    public NetFSERecord generate() {
        return new IPTablesRecord();
    }

    public boolean isSyslog() {
        return true;
    }

   

}
